import * as Cesium from "cesium";
class VisibilityAnalyzer {
  constructor(viewer) {
    this.viewer = viewer;
    this.pointsEntity = [];
    this.linesEntity = [];
    this.labelsEntity = [];
    this.handler = null;
    this.points = [];
  }

  // 线性插值生成多个点
  interpolatePoints(start, end, count) {
    const positions = [];
    const step = Cesium.Cartesian3.subtract(
      end,
      start,
      new Cesium.Cartesian3()
    );
    Cesium.Cartesian3.multiplyByScalar(step, 1 / (count - 1), step);

    for (let i = 0; i < count; i++) {
      const position = Cesium.Cartesian3.add(
        start,
        Cesium.Cartesian3.multiplyByScalar(step, i, new Cesium.Cartesian3()),
        new Cesium.Cartesian3()
      );
      positions.push(position);
    }

    return positions;
  }
  // 开始通视分析
  start() {
    this.clearAll();
    this.points = [];

    // 创建事件处理器
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);

    // 左键点击添加点
    this.handler.setInputAction((click) => {
      const cartesian = this.viewer.scene.pickPosition(click.position);
      if (!cartesian) return;

      this.points.push(cartesian);

      // 添加点实体
      const pointEntity = this.viewer.entities.add({
        position: cartesian,
        point: {
          pixelSize: 10,
          color: Cesium.Color.YELLOW,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
      });

      this.pointsEntity.push(pointEntity);

      // 当收集到两个点时进行分析
      if (this.points.length === 2) {
        this.stop();
        this.analyzeLineOfSight(this.points[0], this.points[1]);
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }

  // 停止分析
  stop() {
    if (this.handler) {
      this.handler.destroy();
      this.handler = null;
    }
  }

  // 清除所有实体
  clearAll() {
    this.stop();

    [this.pointsEntity, this.linesEntity, this.labelsEntity].forEach(
      (entityArray) => {
        entityArray.forEach((entity) => this.viewer.entities.remove(entity));
        entityArray.length = 0;
      }
    );

    this.points = [];
  }

  // 执行通视分析
  async analyzeLineOfSight(start, end) {
    try {
      // 检查是否有地形数据
      // if (!this.viewer.terrainProvider.ready) {
      //   console.error('地形数据未准备好，无法进行通视分析');
      //   return;
      // }

      // 插值生成多个点进行采样
      const positions = this.interpolatePoints(start, end, 100);
      const cartographicArray = positions.map((pos) =>
        Cesium.Cartographic.fromCartesian(pos)
      );

      // 获取地形高度
      const terrainSamples = await Cesium.sampleTerrainMostDetailed(
        this.viewer.terrainProvider,
        cartographicArray
      );

      const startCarto = Cesium.Cartographic.fromCartesian(start);
      const endCarto = Cesium.Cartographic.fromCartesian(end);
      const startHeight = startCarto.height;
      const endHeight = endCarto.height;

      // 计算视线与地形的交点
      let visibleIndex = positions.length - 1;
      for (let i = 1; i < terrainSamples.length; i++) {
        const t = i / (terrainSamples.length - 1);
        const rayHeight = startHeight + (endHeight - startHeight) * t;
        if (terrainSamples[i].height > rayHeight) {
          visibleIndex = i - 1;
          break;
        }
      }

      // 绘制可视线段
      if (visibleIndex >= 1) {
        const visibleLine = this.viewer.entities.add({
          polyline: {
            positions: positions.slice(0, visibleIndex + 1),
            width: 4,
            material: Cesium.Color.GREEN,
            depthFailMaterial: Cesium.Color.GREEN,
          },
        });
        this.linesEntity.push(visibleLine);
      }

      // 绘制不可视线段
      if (visibleIndex < positions.length - 1) {
        const invisibleLine = this.viewer.entities.add({
          polyline: {
            positions: positions.slice(visibleIndex),
            width: 4,
            material: Cesium.Color.RED,
            depthFailMaterial: Cesium.Color.RED,
          },
        });
        this.linesEntity.push(invisibleLine);
      }

      // 显示分析结果
      this.showInfoLabel(
        start,
        end,
        visibleIndex === positions.length - 1,
        terrainSamples[0].height
      );
    } catch (error) {
      console.error("通视分析出错:", error);
      // 可以在这里添加错误提示UI
    }
  }

  // 显示信息标签
  showInfoLabel(start, end, visible, startHeight) {
    const startCarto = Cesium.Cartographic.fromCartesian(start);
    const endCarto = Cesium.Cartographic.fromCartesian(end);

    // 计算水平距离（忽略高度）
    const startFlat = Cesium.Cartesian3.fromRadians(
      startCarto.longitude,
      startCarto.latitude,
      0
    );
    const endFlat = Cesium.Cartesian3.fromRadians(
      endCarto.longitude,
      endCarto.latitude,
      0
    );

    const horizontal = Cesium.Cartesian3.distance(startFlat, endFlat);
    const vertical = Math.abs(start.z - end.z);
    const spatial = Cesium.Cartesian3.distance(start, end);

    const info =
      `水平距离: ${(horizontal / 1000).toFixed(2)}km\n` +
      `垂直距离: ${(vertical / 1000).toFixed(2)}km\n` +
      `空间距离: ${(spatial / 1000).toFixed(2)}km\n` +
      `起点海拔: ${startHeight.toFixed(2)}m\n` +
      `是否可视: ${visible ? "是" : "否"}`;

    const labelEntity = this.viewer.entities.add({
      position: end,
      label: {
        text: info,
        font: "16px sans-serif",
        fillColor: Cesium.Color.WHITE,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        showBackground: true,
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
        pixelOffset: new Cesium.Cartesian2(120, 0),
      },
    });

    this.labelsEntity.push(labelEntity);
  }

  // 辅助函数：在两点之间插值生成多个点
  interpolatePoints(start, end, numPoints) {
    const result = [];
    for (let i = 0; i <= numPoints; i++) {
      const cartesian = Cesium.Cartesian3.lerp(
        start,
        end,
        i / numPoints,
        new Cesium.Cartesian3()
      );
      result.push(cartesian);
    }
    return result;
  }
}
export default VisibilityAnalyzer;
